#encoding=utf-8
from flask_sqlalchemy import SQLAlchemy
from contextlib import contextmanager
from functools import wraps

#应用于运维后台本身的数据库
inner_db = SQLAlchemy()

def db_query_record(table_schema, filter_info= {}):
    if not filter_info:
        records = table_schema.query.all()
    else:
        records = table_schema.query.filter_by(**filter_info)
    data = []
    for record in records:
        data.append(record.get_data_info())

    return data

def db_delete_record(session, table_schema, filter_info):
    recods = table_schema.query.filter_by(**filter_info).all()
    for record in recods:
        session.delete(record)

def db_update_record(session, table_schema, filter_info, update_info):
    records = table_schema.query.filter_by(**filter_info).all()
    if not records:
        raise Exception("record not find by filter info:{}".format(filter_info))

    for record in records:
        for key in update_info:
            if hasattr(record, key):
                setattr(record, key, update_info[key])

def db_add_record(session, table_schema, filter_info, add_info):
    if filter_info:
        records = table_schema.query.filter_by(**filter_info).first()
        if records:
            raise Exception("record has already existed by filter info:{}".format(filter_info))

    table_instance = table_schema(**add_info)
    session.add(table_instance)

def db_add_record_if_not_exist(session, table_schema, filter_info, add_info):
    if filter_info:
        record = table_schema.query.filter_by(**filter_info).first()
        if record:
            return record

    table_instance = table_schema(**add_info)
    session.add(table_instance)

    return table_instance

@contextmanager
def db_transaction_context(db_session):
    try:
        yield  db_session
        print("enter db_transaction_context before commit")
        db_session.commit()
    except Exception as error:
        print(error)
        db_session.rollback()
        raise error

def db_transaction(db_session):
    def wrapper(fun):
        @wraps(fun)
        def decorator(*args, **kwargs):
            print("enter db_transaction")
            with db_transaction_context(db_session):
                return fun(*args, **kwargs)
        return decorator
    return wrapper
